#include "database/file_dao.hpp"
#include "database/db_connection.hpp"
#include <sstream>

bool FileDao::saveFile(const FileInfo& file) {
    DBConnection* db = DBConnection::getInstance();

    std::stringstream ss;
    ss << "INSERT INTO tbl_file (uid, filename, hashcode, size) VALUES ("
       << file.uid << ", '"
       << db->escapeString(file.filename) << "', '"
       << db->escapeString(file.hashcode) << "', "
       << file.size << ")";

    return db->execute(ss.str());
}


std::vector<FileInfo> FileDao::getFilesByUser(int uid, int limit) {
    std::vector<FileInfo> files;
    DBConnection* db = DBConnection::getInstance();

    std::stringstream ss;
    ss << "SELECT id, uid, filename, hashcode, size, created_at, last_update, status "
       << "FROM tbl_file WHERE uid = " << uid << " AND status = 0 "
       << "ORDER BY created_at DESC LIMIT " << limit;

    MYSQL_RES* result = db->query(ss.str());
    if (!result) {
        return files;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        FileInfo file;
        file.id = std::stoi(row[0] ? row[0] : "0");
        file.uid = std::stoi(row[1] ? row[1] : "0");
        file.filename = row[2] ? row[2] : "";
        file.hashcode = row[3] ? row[3] : "";
        file.size = std::stoll(row[4] ? row[4] : "0");
        file.created_at = row[5] ? row[5] : "";
        file.last_update = row[6] ? row[6] : "";
        file.status = std::stoi(row[7] ? row[7] : "0");
        
        files.push_back(file);
    }

    mysql_free_result(result);
    return files;
}


std::optional<FileInfo> FileDao::getFileByHashAndUser(const std::string& hashcode, int uid) {
    DBConnection* db = DBConnection::getInstance();

    std::stringstream ss;
    ss << "SELECT id, uid, filename, hashcode, size, created_at, last_update, status "
       << "FROM tbl_file WHERE hashcode = '" << db->escapeString(hashcode)
       << "' AND uid = " << uid << " AND status = 0";

    MYSQL_RES* result = db->query(ss.str());
    if (!result) {
        return std::nullopt;
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    if (!row) {
        mysql_free_result(result);
        return std::nullopt;
    }

    FileInfo file;
    file.id = std::stoi(row[0] ? row[0] : "0");
    file.uid = std::stoi(row[1] ? row[1] : "0");
    file.filename = row[2] ? row[2] : "";
    file.hashcode = row[3] ? row[3] : "";
    file.size = std::stoll(row[4] ? row[4] : "0");
    file.created_at = row[5] ? row[5] : "";
    file.last_update = row[6] ? row[6] : "";
    file.status = std::stoi(row[7] ? row[7] : "0");  

    mysql_free_result(result);
    return file;
}

/*bool FileDao::deleteFile(int fileId) {*/
    /*DBConnection* db = DBConnection::getInstance();*/

    /*// 使用软删除，将status设置为1表示已删除*/
    /*std::stringstream ss;*/
    /*ss << "UPDATE tbl_file SET status = 1 WHERE id = " << fileId;*/

    /*return db->execute(ss.str());*/
/*}*/


bool FileDao::deleteFileByUser(int fileId, int userId) {
    DBConnection* db = DBConnection::getInstance();
    if (!db || !db->getConnection()) {
        return false;
    }

    std::stringstream ss;
    ss << "UPDATE tbl_file SET status = 1 WHERE id = " << fileId 
       << " AND user_id = " << userId;

    // db->execute() 会返回操作是否成功。
    return  db->execute(ss.str());
}

bool FileDao::updateFileStatus(const std::string& hashcode, int status) {
    DBConnection* db = DBConnection::getInstance();
    if (!db || !db->getConnection()) {
        // 如果数据库连接无效，直接返回失败
        return false;
    }

    std::stringstream ss;
    // 构造 SQL UPDATE 语句
    // 根据文件的 hashcode 来更新它的 status 字段
    ss << "UPDATE tbl_file SET status = " << status
       << " WHERE hashcode = '" << db->escapeString(hashcode) << "'";

    // 执行 SQL 语句并返回结果
    return db->execute(ss.str());
}
